#ifndef RECONOCEDOR_H
#define RECONOCEDOR_H
#include <stdlib.h>
#include <vector>
#include <stdio.h>
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <fstream>
#include <sstream>
#include <dirent.h>
#include <glob.h>
#include "Matriz.h"
#include "TFloat.h"

using namespace std;

/** Esto le permite a un vector mostrarse por pantalla **/
template <typename T>
ostream& operator<<(ostream& output, vector<T> v){
    uint i;
    for (i = 0; i < v.size() - 1; i++)
        output << v[i] << ", ";
    output << v[i];
    return output;
}

class Reconocedor{
public:
    Reconocedor();
    /**
    * Constructor.
    * k es la cantidad de componentes principales a utilizar,
    * precision es la precision de los TFloat.
    */
    Reconocedor(int precision, int k){
        precision = precision;
        k = k;
    }
    /**
    * Leer directorio
    * Lee todas las fotos en un directorio y las carga en forma de vectores.
    * Tienen que estar en texto, con el formato específico de matrices,
    * y con extensión '.new'.
    */
    void leer_dir(string dir);
    /**
    * Cargar
    * Toma un vector no vacío de fotos del mismo tamaño (en forma de matrices) y las guarda
    * en la estructura interna ("achatadas" en vectores por filas).
    */
    void cargar(vector<Matriz> fotos);
    /**
    * Calcular promedio
    * Calcula y almacena el vector promedio. Requiere que haya fotos cargadas.
    */
    void calcular_promedio();
    /**
    * Calcular matriz de covarianza
    * Calcula y almacena la matriz de covarianza. Requiere que el promedio
    * haya sido calculado.
    */
    void calcular_covarianza();
    /**
    * Calcular autovecotres
    * Calcula y almacena los autovectores de la matriz de covarianza.
    * Requiere que la matriz de covarianza haya sido calculada.
    */
    void calcular_autovectores();
    /**
    * Entrenar
    * Calcula y almacena tanto el promedio como la matriz de covarianza.
    * Adivinaron: requiere que haya fotos cargadas.
    */
    void entrenar();
    /**
    * Getters
    */
    const vector<TFloat> dame_promedio() const{
        return promedio;
    }
    const vector< string > dame_fotos_nombres() const{
        return fotos_nombres;
    }
    Matriz dame_covarianza() const{
        return covarianza;
    }
    const vector< vector< TFloat > > dame_fotos() const{
        return fotos;
    }

private:
    /************************ Estructura interna *****************************/
    vector< vector< TFloat > > fotos;
    vector< string > fotos_nombres;
    vector< TFloat > promedio;
    Matriz covarianza;
    Matriz autovectores;
    size_t precision;
    int k; //cantidad de componentes principales a usar

};

#endif // RECONOCEDOR_H
